package com.vc.audio;

import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
public class AudioPlayer extends Thread {
	
	private static final String TAG = "MVAudio";

	boolean bIsPlaying = false;
	boolean bIsPause = false;
	boolean bIsMute = false;

	// static final int frequency = 8000;
	int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
	static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

	private int playBufSize = 0;
	private byte[] playBuffer = null;
	private byte[] frmBuffer = null;
	private int nSamplerate = 0;
	private int nChannels = 0;
	private int nFrameLenInMs = 0;

	// int nPlayBuffNum = 0;
	int nFrameLen = 0;

	AudioTrack audioTrack = null;
	AudioPlayDevCallBack pDevCallBack = null;

	private float volume = 0;

	Context context;

	public int Init(Context mCtxt) {
		context = mCtxt;

		// AudioServiceConfig();

		if (nChannels == 2) {
			channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
		} else {
			channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
		}

		playBufSize = android.media.AudioTrack.getMinBufferSize(nSamplerate,
				channelConfiguration, audioEncoding);

		if (playBufSize == AudioTrack.ERROR_BAD_VALUE
				|| playBufSize == AudioTrack.ERROR) {
			return 0;
		}

		if (AudioSettingManager.isSwitchSpkModeEnable()) {
			audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, nSamplerate,
					channelConfiguration, audioEncoding,
					playBufSize,AudioTrack.MODE_STREAM);
		}else{
			audioTrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
					nSamplerate, channelConfiguration, audioEncoding,
					playBufSize, AudioTrack.MODE_STREAM); 
		}

		if (null == audioTrack)
			return 0;

		playBuffer = new byte[playBufSize];

		if (null == playBuffer)
			return 0;
		frmBuffer = new byte[nFrameLen];
		if (null == frmBuffer)
			return 0;

		// nPlayBuffNum = 1;

		bIsPlaying = false;
		bIsPause = false;

		// set track volume...
		// float maxV = AudioTrack.getMaxVolume();
		// volume = maxV*10/10;
		// audioTrack.setStereoVolume(volume, volume);

		return 1;
	}

	public void SetDevCallBack(AudioPlayDevCallBack pCallBack) {
		pDevCallBack = pCallBack;
	}

	public int Uninit() {
		audioTrack.release();
		bIsPlaying = false;
		bIsPause = false;
		return 1;
	}

	public int SetPlayFormat(int samplerate, int channels, int frmdur) {
		if (true == bIsPlaying)
			return 0;

		nSamplerate = samplerate;
		nChannels = channels;
		nFrameLenInMs = frmdur;

		nFrameLen = (nSamplerate / 1000) * channels * nFrameLenInMs * 2;

		return 1;
	}

	public int GetFrameLen() {
		return nFrameLen;
	}

	public int StartPlay() {
		if (true == bIsPlaying)
			return 1;

		// AudioServiceConfig();

		bIsPlaying = true;
		audioTrack.play();

		int state = audioTrack.getState();
		if (AudioTrack.STATE_UNINITIALIZED == state)
			return 0;

		// star thread process....
		start();

		return 1;

	}

	public int StopPlay() {
		if (false == bIsPlaying)
			return 1;

		bIsPlaying = false;
		// stop();

		try {
			join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		audioTrack.stop();

		return 1;
	}

	public int PausePlay() {
		bIsPause = true;
		audioTrack.pause();

		return 1;
	}

	public int PlayMute(boolean bPause) {
		bIsMute = bPause;
		return 0;
	}

	// volume control...
	public void SetVolume(float fVol) {
		volume = fVol;

		if (null != audioTrack) {
			audioTrack.setStereoVolume(volume, volume);
		}
	}
	
	private void calc(short[] lin,int off,int len) {
		int i,j;
		for (i = 0; i < len; i++) {
		j = lin[i+off];
		lin[i+off] = (short)(j>>2);
		}
	}

	// thread loop...
	public void run() {
		/*
		 * BufferedOutputStream out = null;
		 * 
		 * try { out = new BufferedOutputStream(new
		 * FileOutputStream("/sdcard/winter/player.pcm")); } catch
		 * (FileNotFoundException e) { // TODO Auto-generated catch block
		 * e.printStackTrace(); }
		 */
		int nLeftLen = 0;

		android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO/*android.os.Process.THREAD_PRIORITY_AUDIO*/);

		//Log.d(UITAG, "start play....");
		while (bIsPlaying) {
			//Log.d(UITAG, "play run");

			if (null != pDevCallBack) {

				pDevCallBack.PlayDevDataCallBack(frmBuffer, nFrameLen);
				/*
				 * try { out.read(frmBuffer, 0, nFrameLen);
				 * 
				 * // out.write(recpcm, 0, recpcm.length); } catch (IOException
				 * e) {
				 * 
				 * // TODO Auto-generated catch block e.printStackTrace();
				 * 
				 * }
				 */
				//if (bIsMute) {
				//	Arrays.fill(frmBuffer, (byte)0x00);
				//}
				
				if (playBufSize >= nFrameLen) {
					audioTrack.write(frmBuffer, 0, nFrameLen);
					
				}
				else 
				{
					// fill the first device frame buffer....
					// int needLen = playBufSize - nLeftLen;
					System.arraycopy(frmBuffer, 0, playBuffer, nLeftLen,
							playBufSize - nLeftLen);

					audioTrack.write(playBuffer, 0, playBuffer.length);

					//
					int nOffset = playBufSize - nLeftLen;
					int nAviableLen = nFrameLen - nOffset;

					while (nAviableLen >= playBufSize) {
						audioTrack.write(frmBuffer, nOffset, playBufSize);

						nOffset += playBufSize;
						nAviableLen -= playBufSize;
					}

					nLeftLen = nAviableLen;
					System.arraycopy(frmBuffer, nOffset, playBuffer, 0,
							nLeftLen);

				}

			}

		}
	}

}